import tkinter as tk;
import tkinter.messagebox;
from tkinter import ttk;
import keyboard,time,threading;
import sys,ctypes,pyautogui;
from plyer import notification;
historical_updates={
    "V1.0.0":"  首版不涉及",
    "V1.0.3":"  修复了一些问题",
    "V1.0.5":"  完整版",
    "V2.0.0":"  2023/12/3窗口布局优化\n  解决了停止点击必须在鼠标点击时的问题",
    "V2.0.1":"  2023/12/23新增置顶，取消“输入好了”按钮，\n添加了每秒点击次数"
}
stop = False;
window_top = False;
pyautogui.PAUSE = 0;
def is_admin():
    try:return ctypes.windll.shell32.IsUserAnAdmin();
    except:return False;
if is_admin():pass;
else:
    ctypes.windll.shell32.ShellExecuteW(None,"runas", sys.executable, __file__, None, 1);
    sys.exit();
value = 0;
def str_historical_updates():
    temp = "";
    global historical_updates;
    #将字典historical_updates全部转化为字符串
    for key,value in historical_updates.items():
        temp = temp + key + "\n" + value + "\n";#用temp变量将返回的结果装下来
    return temp;
def val(number):
    global value;
    value = number;
def thread_wait_press():
    global stop;
    while keyboard.is_pressed('ctrl+t') == False:
        pass;time.sleep(0.01);
    stop = True;
def thread_click_number():
    global stop,click_number;
    while stop != True:
        time.sleep(1.01);
        if stop != True:#这里是防止用户在等待的时间就停止
            lb_click_count.config(bg="green",text="每秒点击次数："+str(click_number));
        click_number = 0;
def func_detect_presses():
    global sleep_time,entered,stop,click_number,combo_selected;
    while True:
        while keyboard.is_pressed('ctrl+k')==False:pass;time.sleep(0.01);
        stop = False;
        try:
            sleep_time=float(entered.get());
        except:
            tkinter.messagebox.showerror("错误","你输入的数值不符合要求，请重新输入");
            continue;
        if sleep_time <= 1.0 == False or not sleep_time >= 0.0:
            tkinter.messagebox.showerror("错误","你输入的数值不符合要求，请重新输入");
        elif combo_selected.get() != "点击左键" and combo_selected.get() != "点击右键":
            tkinter.messagebox.showerror("错误","你没有选择点击的键");
        else:
            notification.notify(title = "连点器",message = "即将开始点击",app_icon = None,timeout = 10)
            lb_click_count.config(bg="green",text="每秒点击次数：即将开始点击")
            thread_wait = threading.Thread(target=thread_wait_press);
            thread_click_number_1 = threading.Thread(target=thread_click_number);
            click_number = 0;
            thread_wait.start();
            thread_click_number_1.start();
            while not stop:
                if combo_selected.get() == "点击左键":
                    thread_click = threading.Thread(target=pyautogui.click);
                    thread_click.start()
                    pyautogui.click(button="left");
                    time.sleep(sleep_time);
                if combo_selected.get() == "点击右键":                                                                                  
                    pyautogui.click(button="right");
                    time.sleep(sleep_time);
                click_number = click_number + 1;
            lb_click_count.config(bg="grey",text="每秒点击次数：当前未连点")
            notification.notify(title = "连点器",message = "已结束",app_icon = None,timeout = 10)
def func_top_floor():
    #执行置顶
    global window,window_top;
    if window_top != True:
        window.attributes('-topmost', 'true');
        window_top = True
    else:
        window.attributes('-topmost', 'false');
        window_top = False
def func_about_exit():
    about_window.destroy();
    window.attributes('-disabled',False);
def func_history_exit():
    history_window.destroy();
    about_window.attributes('-disabled',False);
def window_undisable():
    window.attributes('-disabled',False);
def about_undisable():
    about_window.attributes('-disabled',False);
    history_window.destroy();
def func_about():
    global about_window,window;
    window.attributes('-disabled',True);
    about_window = tk.Tk();
    about_window.title("关于连点器");
    about_window.geometry("250x150");
    about_window.resizable(False,False);
    about_window.attributes("-toolwindow", 2);
    lb_about = tk.Label(about_window,text="鼠标连点器  V2.0.1\n-2023年12月23日-\n本次更新内容：\n1、置顶选项\n2、取消“输入好了”按钮"+
                        "3、新增每秒点击次数",justify='left');
    bt_about_update = tk.Button(about_window,text="历史更新记录",command=func_history);
    bt_about_exit = tk.Button(about_window,text="关闭",command=func_about_exit);
    lb_about.grid(row=0,column=0,padx=(0,0),pady=0,columnspan=2);
    bt_about_exit.grid(row=1,column=1,padx=(0,0),pady=0);
    bt_about_update.grid(row=1,column=0,padx=(0,0),pady=0);
    about_window.protocol("WM_DELETE_WINDOW",window_undisable)
    about_window.mainloop();
def func_history(): 
    global history_window,about_window;
    about_window.attributes('-disabled',True);
    history_window = tk.Tk();
    history_window.title("历史更新记录");
    history_window.geometry("400x210");
    history_window.resizable(False,False);
    history_window.attributes("-toolwindow", 2);
    lb_history = tk.Label(history_window,text=str_historical_updates(),anchor='w',justify='left');
    bt_history_exit = tk.Button(history_window,text="关闭",command=func_history_exit);
    lb_history.pack();
    bt_history_exit.pack();
    history_window.protocol("WM_DELETE_WINDOW",about_undisable)
    history_window.mainloop();
def window_exit():
    window.destroy();
    sys.exit(0);
detect_presses = threading.Thread(target=func_detect_presses);
detect_presses.start();#用多线程判断用户是否按下ctrl+k
window = tk.Tk();
window.title("连点器");
window.geometry("270x270");
window.resizable(False,False);
window.protocol("WM_DELETE_WINDOW",window_exit);
top_floor = False;
top = tk.Menu(window);
top.add_cascade(label="关于",command=func_about);
window.config(menu=top);
lb = tk.Label(window,text="点击间隔(0-1之间)：",width=20,fg="black");
combo_selected = tkinter.StringVar();
combo = ttk.Combobox(window, textvariable=combo_selected,width=7);
combo.configure(state="readonly");
combo["value"] = ("点击左键","点击右键");
entered = tkinter.StringVar();
text = tk.Entry(window,width=4,textvariable=entered);
lb_2 = tk.Label(window,text="选择点击左键/右键：",width=24,fg="black",height=2);
lb_3 = tk.Label(window,text="按下 contral+k 开始   按下 contral+t 停止",width=34,fg="black");
lb_click_count = tk.Label(window,text="每秒点击次数：当前未连点",bg="grey",font=("微软雅黑", 10));
check_top_set_value = tk.StringVar();
check_top_window=ttk.Checkbutton(window,text="置顶窗口",variable=check_top_set_value,onvalue="置顶",offvalue="不置顶",command=func_top_floor);
lb.grid(row=0,column=0,padx=(0,0),pady=0,sticky="W");
text.grid(row=0,column=1,padx=(0,0),pady=0,sticky="W");
combo.grid(row=1,column=1,padx=(0,0),pady=0,sticky="W");
lb_2.grid(row=1,column=0,padx=(0,0),pady=0,sticky="W");
lb_3.grid(row=2,column=0,padx=(0,0),pady=0,columnspan=2);
check_top_window.grid(row=3,column=0,padx=(0,0),pady=0);
lb_click_count.grid(row=4,column=0,padx=(0,0),columnspan=2);
tk.mainloop();